/*
 * Project: Sudoku Hint Engine for Android
 * Copyright (C) 2010-2013 Emanuel Moecklin
 * 
 * Available under the terms of the Lesser General Public License (LGPL)
 */
package com.onegravity.sudoku.solver.rules.uniqueness;

import java.util.ArrayList;
import java.util.BitSet;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.net.Uri;

import com.onegravity.sudoku.solver.HintResource;
import com.onegravity.sudoku.solver.HintType;
import com.onegravity.sudoku.solver.core.IndirectHint;
import com.onegravity.sudoku.solver.core.Rule;
import com.onegravity.sudoku.solver.data.Cell;
import com.onegravity.sudoku.solver.data.ImmutableCell;
import com.onegravity.sudoku.solver.data.Region;
import com.onegravity.sudoku.solver.util.BitSetFactory;
import com.onegravity.sudoku.solver.util.HtmlLoader;
import com.onegravity.sudoku.solver.util.Link;

public class HiddenUniqueRectangleHint extends IndirectHint implements Rule {

	private static final long serialVersionUID = -2836551837474894338L;
	
	private final List<Cell> rectangleCells;
	private final int a;
	private final int b;
	private final Region region1;
	private final Region region2;

    public HiddenUniqueRectangleHint(List<Cell> rectangleCells, int a, int b, Region region1, Region region2) {
        super(Collections.singletonMap(rectangleCells.get(3), BitSetFactory.createOneElement(b)));
        this.rectangleCells = rectangleCells;
        this.a = a;
        this.b = b;
        this.region1 = region1;
        this.region2 = region2;
    }

    @Override
    public Collection<Cell> getSelectedCells(HintType hintType) {
    	switch(hintType) {
    	case SMALL_CLUE: return rectangleCells;
    	default:
    	case BIG_CLUE:
    	case HINT:
    		List<Cell> tmp = new ArrayList<Cell>(rectangleCells);
    		tmp.remove(3);
    		return tmp;
    	}
    }

    @Override
    public Map<Cell, BitSet> getSelectedPotentials(HintType hintType, int viewNum) {
        if (hintType!=HintType.BIG_CLUE) return null;
        Map<Cell, BitSet> result = new HashMap<Cell, BitSet>();
        result.put(rectangleCells.get(3), BitSetFactory.createOneElement(b));
        return result;
    }
    
    @Override
    public Map<ImmutableCell, BitSet> getRemovedPotentials(HintType hintType) {
        return (hintType==HintType.HINT) ? super.getRemovedPotentials(hintType) : null;
    }

    @Override
    public Collection<Link> getLinks(HintType hintType, int viewNum) {
        if (hintType!=HintType.HINT) return null;
        Collection<Link> result = new ArrayList<Link>();
        result.add(new Link(rectangleCells.get(0), 0, rectangleCells.get(1), 0));
        result.add(new Link(rectangleCells.get(1), 0, rectangleCells.get(3), 0));
        result.add(new Link(rectangleCells.get(3), 0, rectangleCells.get(2), 0));
        result.add(new Link(rectangleCells.get(2), 0, rectangleCells.get(0), 0));
        return result;
    }
    
    @Override
    public Region[] getRegions(HintType hintType) {
    	if (hintType!=HintType.HINT) return null;
        return new Region[] {region1, region2};
    }
    
    @Override
    public double getDifficulty() {
        return 4.8;
    }

    @Override
    public String getHintHtml(HintType hintType) {
        Cell cellA = rectangleCells.get(0);
        Cell cellB = rectangleCells.get(1);
        Cell cellC = rectangleCells.get(2);
        Cell cellD = rectangleCells.get(3);
        String html = HtmlLoader.loadHtml(HintResource.HIDDEN_UNIQUE_RECTANGLE.hint(hintType));
        return HtmlLoader.format(html, cellA.toString(), cellB.toString(), cellC.toString(), cellD.toString(), a, b, region1.toFullString(), region2.toFullString());
    }

	@Override
	public String getName() {
		return HintResource.HIDDEN_UNIQUE_RECTANGLE.getName();
	}

    @Override
    public Uri getLink() {
    	return HintResource.HIDDEN_UNIQUE_RECTANGLE.getUrl();
	}

	@Override
	public String toString() {
        Cell[] cells = new Cell[4];
        rectangleCells.toArray(cells);
        return getName() + ": " + Cell.toFullString(cells) + " " + a + ", " + b; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
	}
	
}